#include "cal.h"
void calculateSolarPosition(double longitude, double latitude, int year, int month, int day, int hour, int minute, int second,
                            double& alpha, double& gamma, double& Hs_sunrise, double& Hs_sunset, int& n) {
    // 计算时差
    double delta_T = (longitude - 120.0) / 15.0;

    // 计算真太阳时
    double Hs = hour + minute / 60.0 + second / 3600.0 + delta_T;

    // 计算时角
    double omega = 15 * (Hs - 12);

    // 计算日期序数n
    if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
        // 闰年
        switch (month) {
        case 1: n = day; break;
        case 2: n = 31 + day; break;
        case 3: n = 60 + day; break;
        case 4: n = 91 + day; break;
        case 5: n = 121 + day; break;
        case 6: n = 152 + day; break;
        case 7: n = 182 + day; break;
        case 8: n = 213 + day; break;
        case 9: n = 244 + day; break;
        case 10: n = 274 + day; break;
        case 11: n = 305 + day; break;
        case 12: n = 335 + day; break;
        }
    }
    else {
        // 平年
        switch (month) {
        case 1: n = day; break;
        case 2: n = 31 + day; break;
        case 3: n = 59 + day; break;
        case 4: n = 90 + day; break;
        case 5: n = 120 + day; break;
        case 6: n = 151 + day; break;
        case 7: n = 181 + day; break;
        case 8: n = 212 + day; break;
        case 9: n = 243 + day; break;
        case 10: n = 273 + day; break;
        case 11: n = 304 + day; break;
        case 12: n = 334 + day; break;
        }
    }

    // 计算太阳赤纬角delta
    double delta = 23.45 * sin(2 * M_PI * (284 + n) / 365);

    // 根据特殊日期调整赤纬角
    if ((month == 3 && day == 21) || (month == 9 && day == 23))
        delta = 0;
    else if (month == 6 && day == 22)
        delta = 23.5;
    else if (month == 12 && day == 22)
        delta = -23.5;

    // 计算太阳高度角alpha
    if (hour == 12 && minute == 0 && second == 0) {
        // 正午时间
        if (latitude > delta)
            alpha = 90 - latitude + delta;
        else
            alpha = 90 + latitude - delta;
    }
    else {
        // 一般时间
        alpha = asin(sin(latitude * M_PI / 180) * sin(delta * M_PI / 180) + cos(latitude * M_PI / 180) * cos(delta * M_PI / 180) * cos(omega * M_PI / 180)) * 180 / M_PI;
    }

    // 计算sin(gamma)
    double sin_gamma = -(sin(omega * M_PI / 180) * cos(delta * M_PI / 180)) / cos(alpha * M_PI / 180);

    // 计算cos(gamma)
    double cos_gamma = (sin(delta * M_PI / 180) - sin(alpha * M_PI / 180) * sin(latitude * M_PI / 180)) / (cos(alpha * M_PI / 180) * cos(latitude * M_PI / 180));

    // 综合求解方位角
    gamma = atan2(sin_gamma, cos_gamma) * 180 / M_PI;

    // 将角度调整为0到360度之间
    if (gamma < 0) {
        gamma += 360;
    }

    // 计算日出、日落的时角omega_s
    double cos_omega_s = -tan(latitude * M_PI / 180) * tan(delta * M_PI / 180);
    double omega_sr = -acos(cos_omega_s) * 180 / M_PI;
    double omega_ss = acos(cos_omega_s) * 180 / M_PI;

    // 计算日出、日落时间（单位：小时）
    Hs_sunrise = 12 - (acos(cos_omega_s) * 180 / M_PI) / 15;
    Hs_sunset = 12 + (acos(cos_omega_s) * 180 / M_PI) / 15;
}

// 批量计算并输出结果
void batchCalculation(double longitude, double latitude, int year, int month, int day, int start_hour, int start_minute, int end_hour, int end_minute, int interval_minute) {
    double alpha, gamma, Hs_sunrise, Hs_sunset;
    int n;

    calculateSolarPosition(longitude, latitude, year, month, day, start_hour, start_minute, 0, alpha, gamma, Hs_sunrise, Hs_sunset, n);

    std::cout << "日期序数n：" << n << std::endl;
    std::cout << "日出时间：" << std::setw(2) << std::setfill('0') << static_cast<int>(Hs_sunrise) << ":" << std::setw(2) << std::setfill('0') << static_cast<int>((Hs_sunrise - static_cast<int>(Hs_sunrise)) * 60) << std::endl;
    std::cout << "日落时间：" << std::setw(2) << std::setfill('0') << static_cast<int>(Hs_sunset) << ":" << std::setw(2) << std::setfill('0') << static_cast<int>((Hs_sunset - static_cast<int>(Hs_sunset)) * 60) << std::endl;

    // 计算并输出每个时间段的太阳高度角和方位角
    int current_hour = start_hour;
    int current_minute = start_minute;
    while (!(current_hour == end_hour && current_minute > end_minute)) {
        calculateSolarPosition(longitude, latitude, year, month, day, current_hour, current_minute, 0, alpha, gamma, Hs_sunrise, Hs_sunset, n);

        std::cout << std::setw(2) << std::setfill('0') << current_hour << ":" << std::setw(2) << std::setfill('0') << current_minute
                  << " 高度角：" << alpha << "°, 方位角：" << gamma << "°" << std::endl;

        current_minute += interval_minute;
        if (current_minute >= 60) {
            current_hour++;
            current_minute -= 60;
        }
    }
}
